#include "SolutionList.h"

list emptyList()
{ 
	return NULL; 
}

int empty(list l)
{
	if (l==NULL) 
		return 1; 
	else 
		return 0; 
}

solution head(list l)
{
	if (empty(l)) 
		abort();	//should never reach this point (always check after if its null)
	else 
		return l->sol; 
}


solution elementAt(list l, int i)
{
	if(i<0 || i>length(l))
	{
		//ERROR: i cannot be negative and it must not be longer than the list length
		printf("INVALID PARAMETERS, ABORTING");
		abort();
	}
	else if(i == 0)
		return head(l);
	else
		return elementAt(tail(l), i-1);
}

list modifyElementAt(list l, solution s, int i)
{
	if(i<0 || i>length(l))
	{
		//ERROR: i cannot be negative or longer than the list length
		printf("INVALID PARAMETERS, ABORTING");
		abort();
	}
	else if(i == 0)
		return cons(tail(l), s);
	else
		return cons(modifyElementAt(tail(l),s,i-1), head(l));
}

list tail(list l)
{
	if (empty(l))	//should never reach this point (always check after if its null)
		abort();	
	else 
		return l->next; 
}

list cons(list l, solution e)
{
	list t = (list) malloc(sizeof(item));
	if(!isSet(e)){
		//printf("\nATTENTION!! THE SOLUTION IS NOT SETTED!!\n");
	}
	t->sol=e; 
	t->next=l; 
	return t; 
}

int length(list l)
{
	if(empty(l))
		return 0;
	return 1 + length(tail(l));
}

list insertInOrderSolution(list l1, solution s, int* index)
{
	if(empty(l1))			//this is called first to prevent head(NULL) = abort()
		return cons(l1,s);
	else
	{
		if(isEqualOrLess(head(l1),s))
			return cons(l1,s);
		else{
			*index = *index + 1;
			return cons(insertInOrderSolution(tail(l1), s, index),head(l1));
		}
	}
}

list copy(list l)
{
	if (empty(l)) 
		return l;
	else 
		return cons(copy(tail(l)), head(l));
}

list append(list l1, list l2)
{
	if (empty(l1)) 
		return l2;
	else 
		return cons(append(tail(l1),l2), head(l1));
}

list reverse(list l)
{
	if (empty(l)) 
		return emptyList();
	else 
		return append(reverse(tail(l)), cons(emptyList(), head(l)));
}

list keepFirstNElements(list l, int num)
{
	list result = emptyList(), temp = copy(l);
	int count;
	if(num<=0){
		//ERROR: cannot be passed a negative num
		printf("\nATTENTION!! YOU PASS A 0/NEGATIVE VALUE!!\n");
		abort();
	}
	else
	{
		for(count = 0; count<num; count++)
		{
			if(empty(temp))
				break;
			result = cons(result,head(temp));
			temp = tail(temp);
		}
	}
	return reverse(result);
}

int lastSolutionValue(list l)
{
	if(empty(l->next))
		return l->sol.value;
	else 
		return lastSolutionValue(l->next);
}

void showList(list l)
{ 
	printf("\n\n***PRINT LIST***\n\n");
	printf("Number of elements: %i\n", length(l));
	while (!empty(l))
	{
		showSolution(head(l));
		l = tail(l);
	} 
	printf("\n\n****************\n\n");
}

void showListValue(list l)
{
	printf("\n\n***PRINT LIST***\n\n");
	printf("Number of elements: %i\n", length(l));
	printf("[");
	while (!empty(l))
	{
		printf("( ");

		showSolutionValue(head(l));
		l = tail(l);

		printf(" )");
	}
	printf("]");
	printf("\n\n****************\n\n");
}